package fr.umlv.proxir.filter;

import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import java.util.regex.Pattern;

/**
 * this class verify if a page is forbidden according to the filtered wors in
 * proxir.properties
 * 
 * @author gourier & motais
 * 
 */
public class Filter {

	private final Set<String> forbiddenPages = new HashSet<String>();
	private final Set<Pattern> forbiddenWords = new HashSet<Pattern>();
	private final Set<Integer> forbiddenPorts = new HashSet<Integer>();
	private final static Logger LOGGER = Logger.getLogger("ProxIR");

	/**
	 * returns true if we know the page is a forbidden one (found previously a
	 * forbidden word in this page)
	 * 
	 * @param pageID
	 *            the request page
	 * @return true if the page is ok
	 */
	public boolean isPageAllowed(String pageID) {
		if (forbiddenPages.contains(pageID))
			return false;
		for (Pattern pat : forbiddenWords) {
			if (pat.matcher(pageID).matches()) {
				addForbiddenPage(pageID);
				return false;
			}
		}
		return true;
	}

	/**
	 * returns true if the request is on an allowed port, false else
	 * 
	 * @param port
	 *            the requested port
	 * @return true if the port is ok
	 */
	public boolean isPortAllowed(int port) {
		return !forbiddenPorts.contains(port);
	}

	/**
	 * returns true if the sentence doesn't contains a forbidden word
	 * 
	 * @param sentence
	 *            the sentence to verify
	 * @return true if the sentence is ok
	 */
	public boolean isSentenceAllowed(String sentence) {
		for (Pattern pat : forbiddenWords) {
			if (pat.matcher(sentence).matches()) {
				LOGGER.fine("this page have the word " + pat.pattern()
						+ " and hence is forbidden");
				return false;
			}
		}

		return true;
	}

	/**
	 * adds a forbidden port in this filter
	 * 
	 * @param port
	 *            the port to forbid
	 */
	public void addForbiddenPort(int port) {
		forbiddenPorts.add(port);
	}

	/**
	 * adds a forbidden word in this filter
	 * 
	 * @param word
	 *            the port to forbid
	 */
	public void addForbiddenWord(String word) {
		forbiddenWords.add(Pattern.compile(".*" + word + ".*"));
	}

	/**
	 * adds a forbidden page in this filter
	 * 
	 * @param pageID
	 *            the page to forbid
	 */
	public void addForbiddenPage(String pageID) {
		forbiddenPages.add(pageID);
	}

	/**
	 * adds forbidden ports in this filter
	 * 
	 * @param ports
	 *            the ports to forbid
	 */
	public void addAllForbiddenPort(int[] ports) {
		for (int i : ports) {
			addForbiddenPort(i);
		}
	}

	/**
	 * adds forbidden ports in this filter (String representation)
	 * 
	 * @param ports
	 *            the ports to forbid
	 */
	public void addAllForbiddenPort(String[] ports) {
		for (String s : ports) {
			if (!s.equals(""))
				addForbiddenPort(Integer.valueOf(s));
		}
	}

	/**
	 * adds forbidden words in this filter 
	 * 
	 * @param words
	 *            the words to forbid
	 */
	public void addAllForbiddenWord(String[] words) {
		for (String s : words) {
			if (!s.equals(""))
				addForbiddenWord(s);
		}
	}

	/**
	 * adds forbidden pages in this filter
	 * 
	 * @param pages
	 *            the pages to forbid
	 */
	public void addAllForbiddenPage(String[] pages) {
		for (String s : pages) {
			if (!s.equals(""))
				addForbiddenPage(s);
		}
	}

}
